from datetime import datetime, timedelta

from sqlalchemy import Result, select
from sqlalchemy.ext.asyncio import AsyncSession

from scaner.core.models import User, TgChatReference, ADS, SearchOrder
from scaner.core.config.log_config import MyLogger
from ..auth import crud as auth_crud


main_logger = MyLogger("main")
logger = main_logger.getChild("bot_api")  # type: ignore


async def check_token_exist(token: str, session: AsyncSession) -> bool:
    result: Result = await session.execute(
        select(TgChatReference).where(TgChatReference.token == token)
    )
    refer: TgChatReference | None = result.scalar_one_or_none()

    return True if refer else False


async def create_chat_reference(
    chat_id: int,
    tg_user_id: int,
    token: str,
    user: User,
    session: AsyncSession,
) -> None:
    logger.info("Создание связи чата и пользователя")

    chat_reference = TgChatReference(
        chat_id=chat_id,
        tg_user_id=tg_user_id,
        user_id=user.id,
        token=token,
    )

    if check_token_exist(token, session):
        logger.info("Токен уже существует")
        return

    session.add(chat_reference)
    await session.commit()


async def get_chat_id_by_user_id(user_id: int, session: AsyncSession) -> int:
    stmt = select(TgChatReference).where(TgChatReference.user_id == user_id)

    result: Result = await session.execute(stmt)
    reference: TgChatReference | None = result.scalar_one_or_none()

    return reference.chat_id if reference else -1


async def get_user_by_token(
    token: str,
    session: AsyncSession,
) -> User | None:

    stmt = select(TgChatReference).where(TgChatReference.token == token)

    result: Result = await session.execute(stmt)
    reference: TgChatReference | None = result.scalar_one_or_none()

    return (
        await auth_crud.get_user_by_id(
            session,
            reference.user_id,
        )
        if reference
        else None
    )


async def get_ads_for_bot(
    user: User,
    session: AsyncSession,
) -> list[ADS]:

    logger.info("Получение списка объявлений для пользователя")

    sub_stmt = (
        select(SearchOrder.id)
        .where(SearchOrder.user_id == user.id)
        .order_by(SearchOrder.created_at.desc())
    )

    seven_days_ago = datetime.now() - timedelta(
        days=7
    )  # Тут задается за какое время брать объявления

    stmt = (
        select(ADS)
        .where(ADS.order_id.in_(sub_stmt))
        .where(ADS.created_at >= seven_days_ago)
    )

    result: Result = await session.execute(stmt)
    ads = list(result.scalars().all())
    logger.debug(ads)

    return list(ads)
